package httpclient

import (
	"bytes"
	"context"
	"io"
	"net/http"
	"net/url"
	"strings"

	"gitee.com/FlyingOnion/httpclient/pool"
)

func New() *http.Client {
	return pool.Global().Get()
}
func NewClientWithTransport(tr http.RoundTripper) *http.Client {
	return pool.Global().GetWithTransport(tr)
}
func Recycle(c *http.Client) {
	pool.Global().Recycle(c)
}

func NewRequest(ctx context.Context, uRL *url.URL, options ...RequestOption) *http.Request {
	req := emptyReq.Clone(ctx)
	for _, opt := range options {
		opt(req)
	}
	req.URL = uRL
	host := uRL.Host
	if strings.LastIndexByte(host, ':') > strings.LastIndexByte(host, ']') {
		host = strings.TrimSuffix(host, ":")
	}
	req.Host = host
	return req
}

func getNoBody() (io.ReadCloser, error) { return http.NoBody, nil }

var emptyReq = http.Request{
	Method:        "GET",
	ContentLength: 0,
	Body:          http.NoBody,
	GetBody:       getNoBody,
}

type RequestOption func(req *http.Request)

func Header(header http.Header) RequestOption {
	return func(req *http.Request) { req.Header = header }
}

func Body(body []byte) RequestOption {
	return func(req *http.Request) {
		if l := int64(len(body)); l > 0 {
			req.ContentLength = l
			req.Body = io.NopCloser(bytes.NewReader(body))
			req.GetBody = func() (io.ReadCloser, error) {
				return io.NopCloser(bytes.NewReader(body)), nil
			}
		}
	}
}

func Method(method string) RequestOption {
	return func(req *http.Request) { req.Method = method }
}
